// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
//
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.designer.ui.query.sections;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.dengues.core.CorePlugin;
import org.dengues.core.metadata.MetadataUtils;
import org.dengues.core.query.ui.ColumnSelectDialog;
import org.dengues.core.query.ui.ComputedColumnDialog;
import org.dengues.core.query.ui.FilterValueDialog;
import org.dengues.core.sql.SqlUtils;
import org.dengues.designer.ui.query.AbstractFormPage;
import org.dengues.model.DenguesModelManager;
import org.dengues.model.database.DatabaseDiagram;
import org.dengues.model.database.SectionColumns;
import org.dengues.model.database.SectionFilters;
import org.dengues.model.database.SectionGroups;
import org.dengues.model.database.SectionHavings;
import org.dengues.model.database.SectionSorts;
import org.dengues.model.database.SectionUnions;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.DialogCellEditor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 2007-12-8 qiang.zhang $
 * 
 */
public abstract class TableSectionPart extends AbstractSectionPart {

    public final static int TYPE_COLUMNS = 560;

    public final static int TYPE_FILTERS = 561;

    public final static int TYPE_GROUPS = 562;

    public final static int TYPE_SORTS = 563;

    public final static int TYPE_UNIONS = 564;

    public final static int TYPE_HAVINGS = 565;

    protected static final String ID_LOGIC = "id_logic";

    protected static final String ID_VALUE = "id_value";

    protected static final String ID_OPERATOR = "id_operator";

    protected static final String ID_COLUMN = "id_column";

    protected static final List<String> FILTER_LOGIC = new ArrayList<String>();

    protected static final List<String> FILTER_OPERATORS = new ArrayList<String>();
    static {
        FILTER_LOGIC.add("AND");
        FILTER_LOGIC.add("OR");

        FILTER_OPERATORS.add("=");
        FILTER_OPERATORS.add(">");
        FILTER_OPERATORS.add("<");
        FILTER_OPERATORS.add(">=");
        FILTER_OPERATORS.add("<=");
        FILTER_OPERATORS.add("<>");
        FILTER_OPERATORS.add("between");
        FILTER_OPERATORS.add("exists");
        FILTER_OPERATORS.add("in");
        FILTER_OPERATORS.add("like");
        FILTER_OPERATORS.add("sounds like");
        FILTER_OPERATORS.add("not between");
        FILTER_OPERATORS.add("not exists");
        FILTER_OPERATORS.add("not in");
        FILTER_OPERATORS.add("not like");
        FILTER_OPERATORS.add("is null");
        FILTER_OPERATORS.add("is not null");
        FILTER_OPERATORS.add("(+)=");
        FILTER_OPERATORS.add("(+)>");
        FILTER_OPERATORS.add("(+)<");
        FILTER_OPERATORS.add("(+)>=");
        FILTER_OPERATORS.add("(+)<=");
        FILTER_OPERATORS.add("(+)<>");
        FILTER_OPERATORS.add("=(+)");
        FILTER_OPERATORS.add(">(+)");
        FILTER_OPERATORS.add("<(+)");
        FILTER_OPERATORS.add(">=(+)");
        FILTER_OPERATORS.add("<=(+)");
        FILTER_OPERATORS.add("<>(+)");
        FILTER_OPERATORS.add("*=");
        FILTER_OPERATORS.add("*>");
        FILTER_OPERATORS.add("*<");
        FILTER_OPERATORS.add("*>=");
        FILTER_OPERATORS.add("*<=");
        FILTER_OPERATORS.add("*<>");
        FILTER_OPERATORS.add("=*");
        FILTER_OPERATORS.add(">*");
        FILTER_OPERATORS.add("<*");
        FILTER_OPERATORS.add(">=*");
        FILTER_OPERATORS.add("<=*");
        FILTER_OPERATORS.add("<>*");

    }

    protected final static List<String> UNIONS = new ArrayList<String>();
    static {
        UNIONS.add("UNION");
        UNIONS.add("UNION ALL");
        UNIONS.add("MINUS");
        UNIONS.add("INTERSECT");

    }

    public final static List<String> ORDERS = new ArrayList<String>();

    static {
        ORDERS.add("ASC");
        ORDERS.add("DESC");

    }

    /**
     * Qiang.Zhang.Adolf@gmail.com TableSectionPart constructor comment.
     * 
     * @param formPage
     * @param parent
     * @param style
     * @param buttonLabels
     */
    public TableSectionPart(AbstractFormPage formPage, Composite parent, String[] buttonLabels) {
        super(formPage, parent, Section.DESCRIPTION, buttonLabels);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com TableSectionPart constructor comment.
     * 
     * @param formPage
     * @param parent
     * @param buttonLabels
     * @param style
     */
    public TableSectionPart(AbstractFormPage formPage, Composite parent, String[] buttonLabels, int style) {
        super(formPage, parent, Section.DESCRIPTION | style, buttonLabels);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.designer.ui.query.sections.AbstractSectionPart#buttonSelected(org.eclipse.swt.widgets.Button,
     * int)
     */
    @Override
    protected void buttonSelected(Button button, int index) {
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.designer.ui.query.AbstractSectionPart#createMainControl(org.eclipse.swt.widgets.Composite, int,
     * int, org.eclipse.ui.forms.widgets.FormToolkit)
     */
    @Override
    protected void createMainControl(Composite parent, int style, int span, FormToolkit toolkit) {
        style |= SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION;
        if (toolkit == null) {
            style |= SWT.BORDER;
        } else {
            style |= toolkit.getBorderStyle();
        }
        viewerPart = new TableViewer(parent, style);
        viewerPart.addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(SelectionChangedEvent e) {
                TableSectionPart.this.selectionChanged((IStructuredSelection) e.getSelection());
            }
        });
        viewerPart.addDoubleClickListener(new IDoubleClickListener() {

            public void doubleClick(DoubleClickEvent e) {
                TableSectionPart.this.handleDoubleClick((IStructuredSelection) e.getSelection());
            }
        });
        viewerPart.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
        ((TableViewer) viewerPart).getTable().setHeaderVisible(true);
        ((TableViewer) viewerPart).getTable().setLinesVisible(true);
        createTableColumns((TableViewer) viewerPart);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "refreshViewerPart".
     */
    public void refreshViewerPart() {
        viewerPart.refresh();
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createTableColumns".
     */
    public abstract void createTableColumns(TableViewer viewerPart);

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "selectionChanged".
     * 
     * @param selection
     */
    protected void selectionChanged(IStructuredSelection selection) {
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "handleDoubleClick".
     * 
     * @param selection
     */
    protected void handleDoubleClick(IStructuredSelection selection) {
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com TableSectionPart class global comment. Detailled comment <br/>
     * 
     * $Id: Dengues.epf 2007-12-15 qiang.zhang $
     * 
     */
    public class ViewerPartProvider implements ITableLabelProvider, IStructuredContentProvider {

        private final int sectionIndex;

        /**
         * Qiang.Zhang.Adolf@gmail.com TableSectionPart.ViewerPartProvider constructor comment.
         */
        public ViewerPartProvider(int sectionIndex) {
            this.sectionIndex = sectionIndex;
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
         */
        public Image getColumnImage(Object element, int columnIndex) {
            return null;
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
         */
        public String getColumnText(Object element, int columnIndex) {
            if (element instanceof SectionColumns) {
                SectionColumns columns = (SectionColumns) element;
                if (columnIndex == 0) {
                    return columns.getName();
                } else if (columnIndex == 1) {
                    return columns.getExpression();
                }
            } else if (element instanceof SectionFilters) {
                SectionFilters filters = (SectionFilters) element;
                if (columnIndex == 0) {
                    return filters.getName();
                } else if (columnIndex == 1) {
                    return filters.getOperator();
                } else if (columnIndex == 2) {
                    return filters.getValue();
                } else if (columnIndex == 3) {
                    return filters.getLogic();
                }
            } else if (element instanceof SectionGroups) {
                SectionGroups filters = (SectionGroups) element;
                if (columnIndex == 0) {
                    return filters.getName();
                } else if (columnIndex == 1) {
                    return filters.getExpression();
                }
            } else if (element instanceof SectionSorts) {
                SectionSorts filters = (SectionSorts) element;
                if (columnIndex == 0) {
                    return filters.getName();
                } else if (columnIndex == 1) {
                    return filters.getOrderBy();
                } else if (columnIndex == 2) {
                    return filters.getExpression();
                }
            } else if (element instanceof SectionHavings) {
                SectionHavings filters = (SectionHavings) element;
                if (columnIndex == 0) {
                    return filters.getName();
                } else if (columnIndex == 1) {
                    return filters.getOperator();
                } else if (columnIndex == 2) {
                    return filters.getValue();
                } else if (columnIndex == 3) {
                    return filters.getLogic();
                }
            } else if (element instanceof SectionUnions) {
                SectionUnions filters = (SectionUnions) element;
                if (columnIndex == 0) {
                    return filters.getName();
                } else if (columnIndex == 1) {
                    return filters.getUnion();
                } else if (columnIndex == 2) {
                    return filters.getQueries();
                }
            }
            return null;
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
         */
        public void addListener(ILabelProviderListener listener) {

        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
         */
        public void dispose() {

        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
         */
        public boolean isLabelProperty(Object element, String property) {
            return false;
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
         */
        public void removeListener(ILabelProviderListener listener) {

        }

        public Object[] getChildren(Object parentElement) {
            if (parentElement instanceof DatabaseDiagram) {
                DatabaseDiagram databaseDiagram = (DatabaseDiagram) parentElement;
                if (sectionIndex == TYPE_COLUMNS) {
                    EList dbChildren = databaseDiagram.getSectionColumns();
                    return dbChildren.toArray(new Object[0]);
                } else if (sectionIndex == TYPE_FILTERS) {
                    return databaseDiagram.getSectionFilters().toArray(new Object[0]);
                } else if (sectionIndex == TYPE_GROUPS) {
                    return databaseDiagram.getSectionGroups().toArray(new Object[0]);
                } else if (sectionIndex == TYPE_SORTS) {
                    return databaseDiagram.getSectionSorts().toArray(new Object[0]);
                } else if (sectionIndex == TYPE_HAVINGS) {
                    return databaseDiagram.getSectionHavings().toArray(new Object[0]);
                } else if (sectionIndex == TYPE_UNIONS) {
                    return databaseDiagram.getSectionUnions().toArray(new Object[0]);
                }
            }
            return new Object[0];
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
         */
        public Object[] getElements(Object inputElement) {
            return getChildren(inputElement);
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
         * java.lang.Object, java.lang.Object)
         */
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

        }

    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getExistNames".
     * 
     * @param type
     * @return
     */
    protected Map<String, Object> getExistNames(int type) {
        Map<String, Object> existNames = new HashMap<String, Object>();
        if (TYPE_COLUMNS == type) {
            for (Object obj : dbDiagram.getSectionColumns()) {
                if (obj instanceof SectionColumns) {
                    existNames.put(((SectionColumns) obj).getName(), obj);
                }
            }
        } else if (TYPE_FILTERS == type) {
            for (Object obj : dbDiagram.getSectionFilters()) {
                if (obj instanceof SectionFilters) {
                    existNames.put(((SectionFilters) obj).getName(), obj);
                }
            }
        } else if (TYPE_GROUPS == type) {
            for (Object obj : dbDiagram.getSectionGroups()) {
                if (obj instanceof SectionGroups) {
                    existNames.put(((SectionGroups) obj).getName(), obj);
                }
            }
        } else if (TYPE_SORTS == type) {
            for (Object obj : dbDiagram.getSectionSorts()) {
                if (obj instanceof SectionSorts) {
                    existNames.put(((SectionSorts) obj).getName(), obj);
                }
            }
        } else if (TYPE_UNIONS == type) {
            for (Object obj : dbDiagram.getSectionUnions()) {
                if (obj instanceof SectionUnions) {
                    existNames.put(((SectionUnions) obj).getName(), obj);
                }
            }
        } else if (TYPE_HAVINGS == type) {
            for (Object obj : dbDiagram.getSectionHavings()) {
                if (obj instanceof SectionHavings) {
                    existNames.put(((SectionHavings) obj).getName(), obj);
                }
            }
        }
        return existNames;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createFilterTableViewer".
     * 
     * @param viewerPart
     */
    protected void createFilterTableViewer(final TableViewer viewerPart, final int dType) {
        Table table = viewerPart.getTable();
        TableColumn column = new TableColumn(table, SWT.NONE);
        column.setText("column");
        column.pack();
        column = new TableColumn(table, SWT.NONE);
        column.setText("operator");
        column.pack();
        column = new TableColumn(table, SWT.NONE);
        column.setText("value");
        column.pack();
        column = new TableColumn(table, SWT.NONE);
        column.setText("logic");
        column.pack();
        ViewerPartProvider provider = new ViewerPartProvider(dType);
        viewerPart.setContentProvider(provider);
        viewerPart.setLabelProvider(provider);
        viewerPart.setInput(dbDiagram);
        viewerPart.setColumnProperties(new String[] { ID_COLUMN, ID_OPERATOR, ID_VALUE, ID_LOGIC });
        final List<DatabaseDiagram> warehouseQueries = CorePlugin.getDefault().getWarehousePluginService()
                .getWarehouseViewFactory().getWarehouseQueries();
        DialogCellEditor columnCellEditor = new DialogCellEditor(table) {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.viewers.DialogCellEditor#openDialogBox(org.eclipse.swt.widgets.Control)
             */
            @Override
            protected Object openDialogBox(Control cellEditorWindow) {
                ColumnSelectDialog dialog = new ColumnSelectDialog(dPage.getEditorSite().getShell(), dbDiagram);
                String columnname = "";
                if (dialog.open() == ColumnSelectDialog.OK) {
                    columnname = dialog.getColumnname();
                    return columnname;
                }
                return null;
            }

        };
        DialogCellEditor valueCellEditor = new DialogCellEditor(table) {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.viewers.DialogCellEditor#openDialogBox(org.eclipse.swt.widgets.Control)
             */
            @Override
            protected Object openDialogBox(Control cellEditorWindow) {
                FilterValueDialog dialog = new FilterValueDialog(dPage.getEditorSite().getShell(), warehouseQueries, getValue());
                String columnname = "";
                if (dialog.open() == FilterValueDialog.OK) {
                    columnname = dialog.getValue();
                    return columnname;
                }
                return null;
            }

        };
        ComboBoxCellEditor opCellEditor = new ComboBoxCellEditor(table, FILTER_OPERATORS.toArray(new String[0]));
        ComboBoxCellEditor logicCellEditor = new ComboBoxCellEditor(table, FILTER_LOGIC.toArray(new String[0]));

        viewerPart.setCellEditors(new CellEditor[] { columnCellEditor, opCellEditor, valueCellEditor, logicCellEditor });
        viewerPart.setCellModifier(new ICellModifier() {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String)
             */
            public boolean canModify(Object element, String property) {
                return true;
            }

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, java.lang.String)
             */
            public Object getValue(Object element, String property) {
                if (dType == TYPE_FILTERS) {
                    SectionFilters filters = (SectionFilters) element;
                    if (property.equals(ID_COLUMN)) {
                        return filters.getName();
                    } else if (property.equals(ID_LOGIC)) {
                        return FILTER_LOGIC.indexOf(filters.getLogic());
                    } else if (property.equals(ID_VALUE)) {
                        return filters.getValue();
                    } else if (property.equals(ID_OPERATOR)) {
                        return FILTER_OPERATORS.indexOf(filters.getOperator());
                    }
                } else if (dType == TYPE_HAVINGS) {
                    SectionHavings filters = (SectionHavings) element;
                    if (property.equals(ID_COLUMN)) {
                        return filters.getName();
                    } else if (property.equals(ID_LOGIC)) {
                        return FILTER_LOGIC.indexOf(filters.getLogic());
                    } else if (property.equals(ID_VALUE)) {
                        return filters.getValue();
                    } else if (property.equals(ID_OPERATOR)) {
                        return FILTER_OPERATORS.indexOf(filters.getOperator());
                    }
                }
                return null;
            }

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, java.lang.String, java.lang.Object)
             */
            public void modify(Object element, String property, Object value) {
                if (value == null) {
                    return;
                }
                element = ((TableItem) element).getData();
                if (element instanceof SectionFilters) {
                    SectionFilters filters = (SectionFilters) element;
                    if (property.equals(ID_COLUMN)) {
                        filters.setName(value.toString());
                    } else if (property.equals(ID_LOGIC)) {
                        filters.setLogic(FILTER_LOGIC.get((Integer) value));
                    } else if (property.equals(ID_VALUE)) {
                        if (value.toString().startsWith(FilterValueDialog.QUERY_PREFIX)) {
                            for (DatabaseDiagram databaseDiagram : warehouseQueries) {
                                if (databaseDiagram.getName().equals(value.toString().substring(1))) {
                                    filters.getProperties().put(SqlUtils.VALUE_SQL, databaseDiagram.getWholeSql());
                                    break;
                                }
                            }
                        } else {
                            filters.getProperties().put(SqlUtils.VALUE_SQL, value.toString());
                        }
                        filters.setValue(value.toString());
                    } else if (property.equals(ID_OPERATOR)) {
                        filters.setOperator(FILTER_OPERATORS.get((Integer) value));
                    }
                } else if (element instanceof SectionHavings) {
                    SectionHavings filters = (SectionHavings) element;
                    if (property.equals(ID_COLUMN)) {
                        filters.setName(value.toString());
                    } else if (property.equals(ID_LOGIC)) {
                        filters.setLogic(FILTER_LOGIC.get((Integer) value));
                    } else if (property.equals(ID_VALUE)) {
                        if (value.toString().startsWith(FilterValueDialog.QUERY_PREFIX)) {
                            for (DatabaseDiagram databaseDiagram : warehouseQueries) {
                                if (databaseDiagram.getName().equals(value.toString().substring(1))) {
                                    filters.getProperties().put(SqlUtils.VALUE_SQL, databaseDiagram.getWholeSql());
                                    break;
                                }
                            }
                        } else {
                            filters.getProperties().put(SqlUtils.VALUE_SQL, value.toString());
                        }
                        filters.setValue(value.toString());
                    } else if (property.equals(ID_OPERATOR)) {
                        filters.setOperator(FILTER_OPERATORS.get((Integer) value));
                    }
                }
                markDirty();
                viewerPart.refresh();
            }

        });
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "buttonFilterSelected".
     * 
     * @param index
     */
    protected void buttonFilterSelected(int index, int sType) {
        MetadataUtils.getColumnsMap(dbDiagram.getDbChildren());
        Iterator<String> iterator = MetadataUtils.getColumnsMap().keySet().iterator();
        if (BUTTON_ADD == index) {
            if (sType == TYPE_FILTERS) {
                SectionFilters sectionFilters = DenguesModelManager.getDatabaseFactory().createSectionFilters();
                if (iterator.hasNext()) {
                    String next = iterator.next();
                    sectionFilters.setName(next);
                } else {
                    sectionFilters.setName("");
                }
                sectionFilters.setLogic(FILTER_LOGIC.get(0));
                sectionFilters.setOperator(FILTER_OPERATORS.get(0));
                sectionFilters.setValue("0");
                sectionFilters.getProperties().put(SqlUtils.VALUE_SQL, "0");
                dbDiagram.getSectionFilters().add(sectionFilters);
            } else if (sType == TYPE_HAVINGS) {
                SectionHavings sectionFilters = DenguesModelManager.getDatabaseFactory().createSectionHavings();
                if (iterator.hasNext()) {
                    String next = iterator.next();
                    sectionFilters.setName(next);
                } else {
                    sectionFilters.setName("");
                }
                sectionFilters.setLogic(FILTER_LOGIC.get(0));
                sectionFilters.setOperator(FILTER_OPERATORS.get(0));
                sectionFilters.setValue("0");
                dbDiagram.getSectionHavings().add(sectionFilters);
            }
            markDirty();
            viewerPart.refresh();
        } else {
            Object o = ((StructuredSelection) viewerPart.getSelection()).getFirstElement();
            if (sType == TYPE_FILTERS) {
                if (o instanceof SectionFilters) {
                    int indexOf = dbDiagram.getSectionFilters().indexOf(o);
                    if (BUTTON_REMOVE == index + 1) {
                        dbDiagram.getSectionFilters().remove(o);
                    } else if (BUTTON_UP == index + 1) {
                        if (indexOf > 0) {
                            dbDiagram.getSectionFilters().move(indexOf - 1, o);
                        }
                    } else if (BUTTON_DOWN == index + 1) {
                        if (indexOf < dbDiagram.getSectionFilters().size() - 1) {
                            dbDiagram.getSectionFilters().move(indexOf + 1, o);
                        }
                    }
                }
            } else if (sType == TYPE_HAVINGS) {
                if (o instanceof SectionHavings) {
                    int indexOf = dbDiagram.getSectionHavings().indexOf(o);
                    if (BUTTON_REMOVE == index + 1) {
                        dbDiagram.getSectionHavings().remove(o);
                    } else if (BUTTON_UP == index + 1) {
                        if (indexOf > 0) {
                            dbDiagram.getSectionHavings().move(indexOf - 1, o);
                        }
                    } else if (BUTTON_DOWN == index + 1) {
                        if (indexOf < dbDiagram.getSectionHavings().size() - 1) {
                            dbDiagram.getSectionHavings().move(indexOf + 1, o);
                        }
                    }
                }
            }
            markDirty();
            viewerPart.refresh();
        }
    }

    protected void handleCCombo(final TableViewer viewerPart, final Table table, final int colIndex, final int sType) {
        final TableEditor editor = new TableEditor(table);
        editor.horizontalAlignment = SWT.LEFT;
        editor.grabHorizontal = true;
        table.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                // Clean up any previous editor control
                Control oldEditor = editor.getEditor();
                if (oldEditor != null) {
                    oldEditor.dispose();
                }
                // Identify the selected row
                final TableItem item = (TableItem) e.item;
                if (item == null) {
                    return;
                }
                final CCombo combo = new CCombo(table, SWT.NONE);
                if (sType == TYPE_UNIONS) {
                    final SectionUnions unions = (SectionUnions) item.getData();
                    combo.setItems(UNIONS.toArray(new String[0]));
                    combo.setText(unions.getUnion());
                } else if (sType == TYPE_SORTS) {
                    final SectionSorts sorts = (SectionSorts) item.getData();
                    combo.setItems(ORDERS.toArray(new String[0]));
                    combo.setText(sorts.getOrderBy());
                }
                combo.setFocus();
                editor.setEditor(combo, item, colIndex);
                Point size = combo.computeSize(SWT.DEFAULT, table.getItemHeight());
                // Set attributes of the editor
                editor.horizontalAlignment = SWT.LEFT;
                editor.minimumHeight = size.y;
                editor.minimumWidth = size.x;
                combo.addSelectionListener(new SelectionAdapter() {

                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        if (sType == TYPE_UNIONS) {
                            final SectionUnions unions = (SectionUnions) item.getData();
                            unions.setUnion(combo.getText());
                            viewerPart.refresh(unions);
                        } else if (sType == TYPE_SORTS) {
                            final SectionSorts sorts = (SectionSorts) item.getData();
                            sorts.setOrderBy(combo.getText());
                            viewerPart.refresh(sorts);
                        }
                        markDirty();
                        viewerPart.refresh();
                    }

                });
                combo.addFocusListener(new FocusListener() {

                    public void focusGained(FocusEvent e) {

                    }

                    /**
                     * Sent when a control loses focus.
                     * 
                     * @param e an event containing information about the focus change
                     */
                    public void focusLost(FocusEvent e) {
                        combo.dispose();
                    }
                });
            }
        });
    }

    protected void handleButtonSelected(int index, int sType) {
        Set<String> existNames = getExistNames(sType).keySet();
        if (BUTTON_ADD == index) {
            ComputedColumnDialog dialog = new ComputedColumnDialog(Display.getDefault().getActiveShell(), dbDiagram, existNames);
            if (ComputedColumnDialog.OK == dialog.open()) {
                switch (sType) {
                case TYPE_COLUMNS: {
                    SectionColumns sectionColumns = DenguesModelManager.getDatabaseFactory().createSectionColumns();
                    sectionColumns.setName(dialog.getName());
                    sectionColumns.setExpression(dialog.getExpression());
                    dbDiagram.getSectionColumns().add(sectionColumns);
                    break;
                }
                case TYPE_GROUPS:
                    SectionGroups sectionGroups = DenguesModelManager.getDatabaseFactory().createSectionGroups();
                    sectionGroups.setName(dialog.getName());
                    sectionGroups.setExpression(dialog.getExpression());
                    dbDiagram.getSectionGroups().add(sectionGroups);
                    break;
                case TYPE_SORTS:
                    SectionSorts sectionSorts = DenguesModelManager.getDatabaseFactory().createSectionSorts();
                    sectionSorts.setName(dialog.getName());
                    sectionSorts.setExpression(dialog.getExpression());
                    sectionSorts.setOrderBy(ORDERS.get(0));
                    dbDiagram.getSectionSorts().add(sectionSorts);
                    break;
                }
                viewerPart.refresh();
                markDirty();
            }
        } else {
            Object o = ((StructuredSelection) viewerPart.getSelection()).getFirstElement();
            if (BUTTON_EDIT == index) {
                switch (sType) {
                case TYPE_COLUMNS:
                    SectionColumns columns = (SectionColumns) o;
                    existNames.remove(columns.getName());
                    ComputedColumnDialog dialog = new ComputedColumnDialog(Display.getDefault().getActiveShell(), dbDiagram,
                            columns.getName(), columns.getExpression(), existNames);
                    if (ComputedColumnDialog.OK == dialog.open()) {
                        columns.setName(dialog.getName());
                        columns.setExpression(dialog.getExpression());
                        viewerPart.refresh();
                        markDirty();
                    }
                    break;
                case TYPE_GROUPS:
                    SectionGroups groups = (SectionGroups) o;
                    existNames.remove(groups.getName());
                    dialog = new ComputedColumnDialog(Display.getDefault().getActiveShell(), dbDiagram, groups.getName(), groups
                            .getExpression(), existNames);
                    if (ComputedColumnDialog.OK == dialog.open()) {
                        groups.setName(dialog.getName());
                        groups.setExpression(dialog.getExpression());
                        viewerPart.refresh();
                        markDirty();
                    }
                    break;
                case TYPE_SORTS:
                    SectionSorts sorts = (SectionSorts) o;
                    existNames.remove(sorts.getName());
                    dialog = new ComputedColumnDialog(Display.getDefault().getActiveShell(), dbDiagram, sorts.getName(), sorts
                            .getExpression(), existNames);
                    if (ComputedColumnDialog.OK == dialog.open()) {
                        sorts.setName(dialog.getName());
                        sorts.setExpression(dialog.getExpression());
                        viewerPart.refresh();
                        markDirty();
                    }
                    break;
                }
            }
            int indexOf = -1;
            if (BUTTON_REMOVE == index) {
                switch (sType) {
                case TYPE_COLUMNS:
                    dbDiagram.getSectionColumns().remove(o);
                    break;
                case TYPE_GROUPS:
                    dbDiagram.getSectionGroups().remove(o);
                    break;
                case TYPE_SORTS:
                    dbDiagram.getSectionSorts().remove(o);
                    break;
                }
            } else if (BUTTON_UP == index) {
                switch (sType) {
                case TYPE_COLUMNS:
                    indexOf = dbDiagram.getSectionColumns().indexOf(o);
                    if (indexOf > 0)
                        dbDiagram.getSectionColumns().move(indexOf - 1, o);
                    break;
                case TYPE_GROUPS:
                    indexOf = dbDiagram.getSectionGroups().indexOf(o);
                    if (indexOf > 0)
                        dbDiagram.getSectionGroups().move(indexOf - 1, o);
                    break;
                case TYPE_SORTS:
                    indexOf = dbDiagram.getSectionSorts().indexOf(o);
                    if (indexOf > 0)
                        dbDiagram.getSectionSorts().move(indexOf - 1, o);
                    break;
                }
            } else if (BUTTON_DOWN == index) {
                switch (sType) {
                case TYPE_COLUMNS:
                    indexOf = dbDiagram.getSectionColumns().indexOf(o);
                    if (indexOf < dbDiagram.getSectionColumns().size() - 1)
                        dbDiagram.getSectionColumns().move(indexOf + 1, o);
                    break;
                case TYPE_GROUPS:
                    indexOf = dbDiagram.getSectionGroups().indexOf(o);
                    if (indexOf < dbDiagram.getSectionGroups().size() - 1)
                        dbDiagram.getSectionGroups().move(indexOf + 1, o);
                    break;
                case TYPE_SORTS:
                    indexOf = dbDiagram.getSectionSorts().indexOf(o);
                    if (indexOf < dbDiagram.getSectionSorts().size() - 1)
                        dbDiagram.getSectionSorts().move(indexOf + 1, o);
                    break;
                }

            }
            markDirty();
            viewerPart.refresh();
        }
    }
}
